<html>
<head><meta charset="utf-8"><title>tell the trait system functions and Write are disjoint? · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html">tell the trait system functions and Write are disjoint?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="213984939"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213984939" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213984939">(Oct 20 2020 at 22:00)</a>:</h4>
<p>I'm trying to add this API:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">E</span>: <span class="nc">std</span>::<span class="n">error</span>::<span class="n">Error</span><span class="p">,</span><span class="w"> </span><span class="n">F</span>: <span class="nb">FnMut</span><span class="p">(</span><span class="o">&amp;</span><span class="p">[</span><span class="kt">u8</span><span class="p">])</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="p">(),</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;&gt;</span><span class="w"> </span><span class="n">OutputSink</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">type</span> <span class="nc">Error</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">E</span><span class="p">;</span><span class="w"></span>

<span class="w">    </span><span class="k">fn</span> <span class="nf">handle_chunk</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">chunk</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="kt">u8</span><span class="p">])</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="p">(),</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="bp">self</span><span class="p">(</span><span class="n">chunk</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">impl</span><span class="o">&lt;</span><span class="n">W</span>: <span class="nc">io</span>::<span class="n">Write</span><span class="o">&gt;</span><span class="w"> </span><span class="n">OutputSink</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">type</span> <span class="nc">Error</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">io</span>::<span class="n">Error</span><span class="p">;</span><span class="w"></span>

<span class="w">    </span><span class="k">fn</span> <span class="nf">handle_chunk</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">chunk</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="kt">u8</span><span class="p">])</span><span class="w"> </span>-&gt; <span class="nc">io</span>::<span class="nb">Result</span><span class="o">&lt;</span><span class="p">()</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="bp">self</span><span class="p">.</span><span class="n">write_all</span><span class="p">(</span><span class="n">chunk</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<p>The compiler is not happy:</p>
<div class="codehilite"><pre><span></span><code>error[E0119]: conflicting implementations of trait `transform_stream::dispatcher::OutputSink`:
  --&gt; src/transform_stream/dispatcher.rs:76:1
   |
68 | impl&lt;E: std::error::Error, F: FnMut(&amp;[u8]) -&gt; Result&lt;(), E&gt;&gt; OutputSink for F {
   | ----------------------------------------------------------------------------- first implementation here
...
76 | impl&lt;W: io::Write&gt; OutputSink for W {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
</code></pre></div>


<p>But I don't think there's any case in which these two traits could overlap. Is there a way to tell that to the compiler?</p>



<a name="213985850"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213985850" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213985850">(Oct 20 2020 at 22:09)</a>:</h4>
<p>There's nothing preventing me on nightly from making a trait that's both of those.</p>



<a name="213985961"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213985961" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213985961">(Oct 20 2020 at 22:10)</a>:</h4>
<p>The way to do this is related to <code>#[fundamental]</code>, but I don't really know exactly what that means.  You might look at how patterns work, since they IIRC have a trait implemented for both functions and <code>&amp;str</code>.</p>



<a name="213985978"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213985978" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213985978">(Oct 20 2020 at 22:10)</a>:</h4>
<p>It might only be possible for specific types, though, not two blanket impls like that.</p>



<a name="213986411"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213986411" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213986411">(Oct 20 2020 at 22:15)</a>:</h4>
<p>To some degree <code>std</code> is "just" a cargo crate (with some special handling wrt. nightly features, etc.).</p>
<p>This means that traits from <code>std</code> are not treated specially in general.(1)</p>
<p>Which means there is no guarantee that something can not implement both <code>FnMut(&amp;[u8]) -&gt; Result&lt;(), E&gt;</code> and <code>io::Write</code>.</p>
<p>E.g. if in future rust versions you <em>might</em> be able to implement <code>Fn</code>/<code>FnMut</code>/<code>FnOnce</code> for your custom types which also can implement <code>io::Write</code>.</p>
<p>So there is currently no way to tell the compiler that the types are disjoint as they might not be disjoint in the future.</p>
<p>This would need negative trait bounds like <code>where W: io::Write + !FnMut(&amp;[u8]) -&gt; Result&lt;(), E&gt;</code>.</p>
<p>(1): Now the fn trait s are <code>#[fundamental]</code> which makes them somewhat special, including allowing the compiler to know that types like <code>str</code> do not and will not implement function traits.</p>



<a name="213986451"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213986451" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213986451">(Oct 20 2020 at 22:15)</a>:</h4>
<p>I didn't see anything special for Pattern:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">impl</span><span class="o">&lt;'</span><span class="na">a</span><span class="p">,</span><span class="w"> </span><span class="n">F</span><span class="o">&gt;</span><span class="w"> </span><span class="n">Pattern</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">F</span><span class="w"></span>
<span class="k">where</span><span class="w"></span>
<span class="w">    </span><span class="n">F</span>: <span class="nb">FnMut</span><span class="p">(</span><span class="kt">char</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">bool</span><span class="p">,</span><span class="w"></span>

<span class="k">impl</span><span class="o">&lt;'</span><span class="na">a</span><span class="p">,</span><span class="w"> </span><span class="o">'</span><span class="na">b</span><span class="o">&gt;</span><span class="w"> </span><span class="n">Pattern</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="o">&amp;'</span><span class="na">b</span><span class="w"> </span><span class="kt">str</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</code></pre></div>

<p>I think it might work because both the type, trait, and impl are in the same crate?</p>



<a name="213986545"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213986545" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213986545">(Oct 20 2020 at 22:16)</a>:</h4>
<p>ah wait I take it back:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[fundamental]</span><span class="w"> </span><span class="c1">// so that regex can rely that `&amp;str: !FnMut`</span>
<span class="cp">#[must_use = </span><span class="s">"closures are lazy and do nothing unless called"</span><span class="cp">]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">trait</span><span class="w"> </span><span class="nb">Fn</span><span class="o">&lt;</span><span class="n">Args</span><span class="o">&gt;</span>: <span class="nb">FnMut</span><span class="o">&lt;</span><span class="n">Args</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="sd">/// Performs the call operation.</span>
<span class="w">    </span><span class="cp">#[unstable(feature = </span><span class="s">"fn_traits"</span><span class="cp">, issue = </span><span class="s">"29625"</span><span class="cp">)]</span><span class="w"></span>
<span class="w">    </span><span class="k">extern</span><span class="w"> </span><span class="s">"rust-call"</span><span class="w"> </span><span class="k">fn</span> <span class="nf">call</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">args</span>: <span class="nc">Args</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span>::<span class="n">Output</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="213986574"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213986574" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213986574">(Oct 20 2020 at 22:17)</a>:</h4>
<blockquote>
<p>This would need negative trait bounds like where W: io::Write + !FnMut(&amp;[u8]) -&gt; Result&lt;(), E&gt;.</p>
</blockquote>
<p>do those have an RFC?</p>



<a name="213986730"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213986730" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213986730">(Oct 20 2020 at 22:19)</a>:</h4>
<p>Indirectly through the orphan rule related rfcs. (EDIT: Wrt.  <code>#[fundamental]</code>, for neg. trait bounds see below).</p>
<p><code>#[fundamental]</code> is a implementation detail which marks thinks as having slightly different, less strickt orphan rules.</p>



<a name="213986963"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213986963" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213986963">(Oct 20 2020 at 22:21)</a>:</h4>
<p>I think there are unapproved or pre-RFCs for negative trait bounds, but I think the currently consensus is that they are a problem wrt. API stability?</p>



<a name="213987302"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213987302" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213987302">(Oct 20 2020 at 22:25)</a>:</h4>
<blockquote>
<p>I think it might work because both the type, trait, and impl are in the same crate?</p>
</blockquote>
<p>Partially, it mainly works because <code>#[fundamental]</code> allows rustc to reason that <code>&amp;str</code> will never implement <code>FnMut(char) -&gt; bool</code>.</p>



<a name="213987728"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213987728" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213987728">(Oct 20 2020 at 22:30)</a>:</h4>
<p>Here is the relevant RFC for <code>#[fundamental]</code>:</p>
<p><a href="https://github.com/rust-lang/rfcs/blob/31a0fef7204657ce542d9595a62765fa0cb8e92b/text/1023-rebalancing-coherence.md">https://github.com/rust-lang/rfcs/blob/31a0fef7204657ce542d9595a62765fa0cb8e92b/text/1023-rebalancing-coherence.md</a></p>
<p>It seems there is currently no pending RFC for negative trait bounds (pending == PR on the RFC repo).</p>



<a name="213988394"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213988394" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213988394">(Oct 20 2020 at 22:39)</a>:</h4>
<p>Through there is a 5Y old <em>closed</em> RFC: <a href="https://github.com/rust-lang/rfcs/pull/586">https://github.com/rust-lang/rfcs/pull/586</a></p>



<a name="213998463"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/213998463" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#213998463">(Oct 21 2020 at 01:13)</a>:</h4>
<p><span class="user-mention" data-user-id="232545">@Joshua Nelson</span> If fully general, negative trait bounds are a massive semver problem, since they make every trait implementation a breaking change.</p>
<p>So anything similar to them will de facto require logic like in specialization to avoid that.  Perhaps you'd only be able to have an impl for <code>A + !B</code> if you also have one for <code>A + B</code>, for example.</p>



<a name="214106429"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/214106429" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#214106429">(Oct 21 2020 at 19:58)</a>:</h4>
<p>I always wondered if we could have opt-in overlapping implementations without any guarantee about which implementation is used. Through I guess this also can make it nightmarish to reason what exactly a program does. So I guess not.</p>



<a name="214107244"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/214107244" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#214107244">(Oct 21 2020 at 20:04)</a>:</h4>
<p>(under the assumption there are no diverging associated types, and the choice is arbitrary at each can site as not all call sites are necessity are of all implementations, and maybe a priority value which the compiler might it might not respect.)</p>



<a name="214107447"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/214107447" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#214107447">(Oct 21 2020 at 20:05)</a>:</h4>
<p>The reason I came to it was because I noticed that the case of theoretical overlapping but practical disjoint implementations is not uncommon and for some patterns the problem of partially overlapping impls where you don't care much which is called on the overlap isn't super rare either.</p>



<a name="214125424"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/214125424" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#214125424">(Oct 21 2020 at 22:58)</a>:</h4>
<p><span class="user-mention silent" data-user-id="209646">Philipp Korber</span> <a href="#narrow/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F/near/214106429">said</a>:</p>
<blockquote>
<p>I always wondered if we could have opt-in overlapping implementations without any guarantee about which implementation is used. Through I guess this also can make it nightmarish to reason what exactly a program does. So I guess not.</p>
</blockquote>
<p>yeah that seems like SFINAE levels of complexity just to figure out what source code is relevant</p>



<a name="214125516"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/214125516" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#214125516">(Oct 21 2020 at 22:59)</a>:</h4>
<p><span class="user-mention silent" data-user-id="125270">scottmcm</span> <a href="#narrow/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F/near/213998463">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="232545">Joshua Nelson</span> If fully general, negative trait bounds are a massive semver problem, since they make every trait implementation a breaking change.</p>
<p>So anything similar to them will de facto require logic like in specialization to avoid that.  Perhaps you'd only be able to have an impl for <code>A + !B</code> if you also have one for <code>A + B</code>, for example.</p>
</blockquote>
<p>that makes sense - could we instead guarantee this in the <em>original</em> library? you'd put <code>impl !FnMut for &amp;str {}</code> in libstd itself, that way everyone can benefit without needing <code>#[fundamental]</code> and it's an explicit part of the API so you don't have to worry about accidental breaking changes</p>



<a name="214131941"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/214131941" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#214131941">(Oct 22 2020 at 00:36)</a>:</h4>
<p>I really wish that the two Writes were cleanly divided, I ran into a similar set of issues here when trying to work with those.</p>



<a name="214132429"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/tell%20the%20trait%20system%20functions%20and%20Write%20are%20disjoint%3F/near/214132429" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F.html#214132429">(Oct 22 2020 at 00:45)</a>:</h4>
<p><span class="user-mention silent" data-user-id="232545">Joshua Nelson</span> <a href="#narrow/stream/122651-general/topic/tell.20the.20trait.20system.20functions.20and.20Write.20are.20disjoint.3F/near/214125516">said</a>:</p>
<blockquote>
<p>that makes sense - could we instead guarantee this in the <em>original</em> library? you'd put <code>impl !FnMut for &amp;str {}</code> in libstd itself, that way everyone can benefit without needing <code>#[fundamental]</code> and it's an explicit part of the API so you don't have to worry about accidental breaking changes</p>
</blockquote>
<p>Sounds like a great idea: <a href="https://internals.rust-lang.org/t/pondering-negative-trait-promises/8265?u=scottmcm">https://internals.rust-lang.org/t/pondering-negative-trait-promises/8265?u=scottmcm</a> <span aria-label="smirk" class="emoji emoji-1f60f" role="img" title="smirk">:smirk:</span></p>
<p>It looks like it even partially happened, though not the coherence parts yet: <a href="https://github.com/rust-lang/rust/pull/68004">https://github.com/rust-lang/rust/pull/68004</a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>